<template>
	<view class="spotTask">
		<view class="spotTask-nav">
			<u-tabs :list="taskList" :is-scroll="false" height="90" :current="currentTask"
				@change="changeTask"></u-tabs>
		</view>
		<view class="spotTask-list ff-font-14">
			<view v-if="spotTaskList.length > 0">
				<view
					class="spotTask-list-box ff-bg-fff ff-margin-12 ff-padding-10 ff-border-radius-10 ff-line-height-1-3"
					v-for="(item, index) of spotTaskList" :key="index">
					<view class="ff-font-15 ff-font-weight-600 ff-color-000">{{ item.projectName }}</view>
					<view class="ff-margin-top-10 ff-margin-bottom-11">
						<view v-if="item.checkStatus == 1">
							<view class="tips ff-margin-right-5 ff-font-12 ff-border-radius-5 ff-color-fff ff-bg-red">
								待处理
							</view>
							<view class="tips tips1 ff-font-12 ff-border-radius-5">
								请在{{ item.maintenanceCheckFaceTime }}分钟以内完成刷脸</view>
						</view>
						<view v-if="item.checkStatus == 2">
							<view class="tips ff-margin-right-5 ff-font-12 ff-border-radius-5 ff-color-fff ff-bg-blue">
								已完成
							</view>
							<view class="tips tips2 ff-font-12 ff-border-radius-5">已完成抽查任务</view>
						</view>
						<view v-if="item.checkStatus == 3">
							<view
								class="tips ff-margin-right-5 ff-font-12 ff-border-radius-5 ff-color-fff ff-bg-7883A1">
								已失效
							</view>
							<view class="tips tips3 ff-font-12 ff-border-radius-5">
								未在{{ item.maintenanceCheckFaceTime }}分钟内完成刷脸
							</view>
						</view>
					</view>
					<view class="ff-bg-777 ff-padding-10 ff-border-radius-10 ff-margin-top-10 ff-font-13 ff-color-666">
						<view class="ff-margin-bottom-6">执 业 人：{{ item.username }}
							{{ item.userPhone }}
						</view>
						<view class="ff-margin-bottom-6">社会单位：{{ item.companyName }}</view>
						<view class="ff-margin-bottom-6">抽查时间：{{ item.checkTime || '--' }}
						</view>
						<view class="ff-margin-top-6" v-if="item.checkStatus == 2">
							完成时间：{{ item.checkResponseTime || '--' }}
						</view>
						<view class="ff-margin-top-6">抽查发起人：{{ item.departmentName || '--' }}</view>
					</view>
					<view v-if="!item.isHistoryData">
						<view v-if="item.checkStatus == 3">
							<view v-if="item.evidenceStatus == 1" class="ff-margin-top-15 ff-margin-bottom-5">
								<u-button @click.stop="submitEvidence(item.id)" type="primary" shape="circle"
									:ripple="true">提交证明材料</u-button>
							</view>
							<view v-else
								class="ff-bg-777 ff-padding-10 ff-border-radius-10 ff-margin-top-10 ff-font-13 ff-color-666">
								<view class="ff-margin-bottom-6">提交时间：{{ item.evidenceSubmitTime || '--' }}
								</view>
								<view class="ff-margin-top-6">
									查收时间：<text
										:class="[item.evidenceReceiveTime?' ':'ff-color-red']">{{ item.evidenceReceiveTime || '未查收' }}</text>
								</view>
								<view v-if="item.evidenceReceiveTime" class="ff-margin-top-6">
									消防救援机构：{{item.evidenceReceiveDepartmentName || '--'}}
								</view>
								<view class="ff-margin-top-10 ff-margin-bottom-5">
									<u-button @click.stop="evidenceDetails(item.id)" type="primary" shape="circle" plain
										:ripple="true">查看证明材料</u-button>
								</view>
							</view>
						</view>
					</view>
					<view class="ff-flex-between ff-align-items-one" v-if="item.checkStatus == 1">
						<view class="ff-align-items-one ff-font-13 ff-color-blue">
							<image
								src="https://fire-system.oss-cn-beijing.aliyuncs.com/web/fire-technology/org-clock.png"
								mode=""></image>
							<view>刷脸认证倒计时：{{ item.countDownTime || '--' }}</view>
						</view>
						<view><u-button @click="brushFaceClick(item)" type="primary" size="mini">定位刷脸</u-button></view>
					</view>
				</view>
				<u-divider v-if="noData" border-color="#909399" height="120" color="#909399"
					bg-color="#f5f5f5">没有更多了</u-divider>
			</view>
			<f-noData v-else></f-noData>
		</view>
		<!-- 组件 -->
		<u-toast ref="uToast" />
		<f-loading ref="loading" />
		<u-back-top :scrollTop="scrollTop" top="200" mode="circle" :iconStyle="iconStyle"
			:customStyle="customstyle"></u-back-top>
		<u-modal v-model="brushFaceModal" title="温馨提示" confirm-text="开始认证" cancel-text="取消认证" show-cancel-button="true"
			@confirm="brushFaceConfirm" :content-style="{ 'line-height': '1.5' }" :content="brushFaceContent" />
		<u-modal :title="failTitle" v-model="failModal" :content-style="{ 'line-height': '1.5' }"
			:content="failContent" />
		<u-modal v-model="locationModal" title="温馨提示" :content-style="{ 'line-height': '1.5' }"
			content="当前位置获取失败，请您开启GPS定位权限后再试！" />
		<u-modal title="录制人脸视频警告" v-model="userWarningModal" @confirm="confirmUserWarning"
			content="为保障精确分析活体人脸，人脸视频录制过程中，请将面部正对手机摄像头并读出：消防技术服务" :content-style="{ 'line-height': '1.5' }" />
	</view>
</template>

<script>
	import {
		mapState
	} from 'vuex';
	import config from '@/tools/config.js';
	export default {
		name: 'spotTask',
		data() {
			return {
				failTitle: '', // 失败弹框的标题
				failContent: '', // 失败弹框的提示语
				failModal: false, // 失败弹框的显/隐
				userWarningModal: false, // 用户录制视频警告弹框
				brushFaceModal: false, // 认证刷脸弹窗显/隐
				brushFaceContent: '', // 认证刷脸内容
				brushFaceInfo: {}, // 当前刷脸的信息
				locationModal: false, // 定位失败弹框显/隐
				// 顶部tabs
				taskList: [{
						name: '待处理'
					},
					{
						name: '已完成'
					},
					{
						name: '已失效'
					}
				],
				currentTask: 0,
				scrollTop: 0,
				iconStyle: {
					fontSize: '32rpx',
					color: '#FFFFFF'
				},
				customstyle: {
					background: '#3B83FE'
				},
				spotTaskList: [], // 抽查任务列表数据
				params: {
					current: 1,
					size: 10,
					checkStatus: 1 // 抽查状态: 1.抽查中 2.抽查完成 3.抽查失败
				},
				noData: false, // 没有更多数据了：显/隐
				timer: null, // 定时器
				// 人脸识别相关
				faceInfo: {
					faceState: false, // 人脸识别（通过true，不通过false）
					sessionId: '', // 百度sessionId
					accessToken: '', // 百度accesstoken
					sessionCode: '', // 用户需要大声读出数字
					videoPath: '', // 上传视频后返回的临时视频路径
					videoBase64: '', // 视频base64
					imageBase64: '', // 图片base64
					latitude: '', // 当前位置维度
					longitude: '' // 当前位置经度
				}
			};
		},
		onPageScroll(e) {
			this.scrollTop = e.scrollTop;
		},
		onLoad(e) {
			getApp().closeScheduledTask() // 关闭定时任务
			if (e.type) {
				this.currentTask = 2
				this.params.checkStatus = 3
				this.getSpotTaskList(); // 获取抽查任务列表
				return
			}
			this.getSpotTaskList(); // 获取抽查任务列表
		},
		onUnload() {
			// setInterval的返回值是一个数值型（1），所以不能加length
			for (let i = 0; i <= this.timer; i++) {
				// 关闭页面所有的定时器
				clearInterval(i);
			}
		},
		computed: {
			...mapState({
				userInfo: modules => modules.infoList.userInfo
			})
		},
		methods: {
			// 上拉加载
			async onReachBottom() {
				this.params.current++;
				await this.getSpotTaskList(); // 获取的数据列表
			},
			// 下拉加载
			async onPullDownRefresh() {
				let that = this
				that.params.current = 1;
				await this.getSpotTaskList(); // 获取的数据列表
				setTimeout(() => {
					that.$refs.uToast.show({
						title: '刷新成功',
						type: 'success'
					});
					uni.stopPullDownRefresh(); // 停止刷新
				}, 100);
			},
			// 顶部tabs的切换
			changeTask(e) {
				this.currentTask = e;
				if (e == 0) {
					this.params.current = 1;
					this.params.checkStatus = 1;
					this.getSpotTaskList(); // 获取抽查任务列表
					return;
				}
				if (e == 1) {
					this.params.current = 1;
					this.params.checkStatus = 2;
					this.getSpotTaskList(); // 获取抽查任务列表
					return;
				}
				if (e == 2) {
					this.params.current = 1;
					this.params.checkStatus = 3;
					this.getSpotTaskList(); // 获取抽查任务列表
					return;
				}
			},
			// 获取抽查任务列表
			async getSpotTaskList() {
				this.$refs.loading.openLoading('加载中···'); // 打开loading动画
				const data = await this.$http.post({
					url: '/serviceOrg/checkTask/userPage',
					data: this.params
				});
				this.$refs.loading.closeLoading(); // 关闭loading动画
				// console.log('获取抽查任务数据列表----', data);
				if (data.code == 200) {
					const infoList = data.data.records;
					if (infoList.length == 0 && this.params.current == 1) {
						// console.log('首次加载没数据');
						this.noData = false;
						this.spotTaskList = [];
					} else if (infoList.length < 3 && this.params.current == 1) {
						// console.log('首次加载有数据，但少于7条');
						this.noData = true;
						this.spotTaskList = infoList;
						this.spotTaskList.forEach(item => {
							// IOS不支持2019-4-1 10:20:30这种格式，只需要将 - 替换为 / 即可解决：.replace(/-/g, "/")
							item.countDown = new Date(item.receiveTime.replace(/-/g, '/')).getTime() + Number(
								item
								.maintenanceCheckFaceTime) * 60 * 1000;
							this.$set(item, 'countDownTime', this.beginTimer() || '00:00:00');
						});
					} else if (infoList.length !== 0 && this.params.current == 1) {
						// console.log('首次加载有数据');
						this.noData = false;
						this.spotTaskList = infoList;
						this.spotTaskList.forEach(item => {
							// IOS不支持2019-4-1 10:20:30这种格式，只需要将 - 替换为 / 即可解决：.replace(/-/g, "/")
							item.countDown = new Date(item.receiveTime.replace(/-/g, '/')).getTime() + Number(
								item
								.maintenanceCheckFaceTime) * 60 * 1000;
							this.$set(item, 'countDownTime', this.beginTimer() || '00:00:00');
						});
					} else if (infoList.length !== 0 && this.params.current > 1) {
						// console.log('上拉加载更多数据');
						this.noData = false;
						this.spotTaskList = this.spotTaskList.concat(infoList);
						this.spotTaskList.forEach(item => {
							// IOS不支持2019-4-1 10:20:30这种格式，只需要将 - 替换为 / 即可解决：.replace(/-/g, "/")
							item.countDown = new Date(item.receiveTime.replace(/-/g, '/')).getTime() + Number(
								item
								.maintenanceCheckFaceTime) * 60 * 1000;
							this.$set(item, 'countDownTime', this.beginTimer() || '00:00:00');
						});
					} else if (infoList.length == 0 && this.params.current > 1) {
						// console.log('上拉加载没有更多数据了');
						this.noData = true;
					}
				}

			},
			// 倒计时系列-------
			beginTimer() {
				// 这个计时器是每秒减去数组中指定字段的时间
				let that = this;
				that.timer = setInterval(() => {
					that.spotTaskList.map(item => {
						let nowTime = new Date().getTime(); //现在时间
						let rightTime = item.countDown - nowTime;
						if (rightTime > 0) {
							let dd = that.fillNumber(rightTime / 1000 / 60 / 60 / 24);
							let hh = that.fillNumber((rightTime / 1000 / 60 / 60) % 24);
							let mm = that.fillNumber((rightTime / 1000 / 60) % 60);
							let ss = that.fillNumber((rightTime / 1000) % 60);
							item.countDownTime = hh + ':' + mm + ':' + ss;
						} else {
							item.countDownTime = '00:00:00';
							clearInterval(that.timer);
						}
					});
				}, 1000);
			},
			fillNumber(num) {
				let number = Math.floor(num); //向下取整
				return number > 9 ? number : '0' + number;
			},
			// 认证刷脸系列
			brushFaceClick(item) {
				if (item.countDownTime == '00:00:00') {
					that.failTitle = '温馨提示'; // 失败的标题
					that.failContent = '任务已超时，无法进行定位刷脸zze2'; // 失败的提示语
					that.failModal = true; // 失败弹框的显/隐
					return
				}
				this.brushFaceInfo = item;
				this.brushFaceContent = `请确认是否开始“${item.projectName}”项目的定位刷脸？`;
				this.brushFaceModal = true;
			},
			// 认证刷脸----点击确定按钮
			brushFaceConfirm() {
				// 获取经纬度
				let that = this;
				uni.getLocation({
					type: 'gcj02',
					success: function(res) {
						// console.log('当前位置的经度-----：', res);
						if (res.latitude && res.latitude) {
							that.$refs.loading.openLoading('定位中···'); // 打开loading动画
							that.faceInfo.longitude = res.longitude;
							that.faceInfo.latitude = res.latitude;
							let positionResult = that.$check.getDistance(that.brushFaceInfo.latitude, that
								.brushFaceInfo
								.longitude, res.latitude, res.longitude); // 计算当前与项目定位的距离
							if (parseFloat(positionResult) * 1000 <= config.location_distance) {
								that.userWarningModal = true;
							} else {
								that.$refs.loading.closeLoading(); // 关闭loading动画
								that.failTitle = '定位失败'; // 失败的标题
								that.failContent =
									`您距离项目所在地中心点超过${config.location_distance}米，请先到维保地点后再定位！`; // 失败的提示语
								that.failModal = true; // 失败弹框的显/隐
							}
						} else {
							that.$refs.loading.closeLoading(); // 关闭loading动画
						}
						that.$refs.loading.closeLoading(); // 关闭loading动画
					},
					fail() {
						that.locationModal = true;
					}
				});
			},
			// 开始人脸识别--点击确定按钮
			confirmUserWarning() {
				let that = this
				uni.chooseVideo({
					count: 1,
					sourceType: ['camera'],
					camera: 'front',
					maxDuration: 5,
					compressed: true,
					success(res) {
						// console.log('返回视频文件的临时文件路径-----', res);
						that.$refs.loading.openLoading('开始人脸认证'); // 打开loading动画
						that.faceInfo.videoPath = res.tempFilePath;
						// 获取全局唯一的文件管理器
						uni.getFileSystemManager().readFile({
							filePath: that.faceInfo.videoPath, //选择视频返回的相对路径
							encoding: 'base64', //编码格式
							success: res => {
								//成功的回调
								that.faceInfo.videoBase64 = res.data;
								// console.log('图片转成base64-------', that.faceInfo.videoBase64);
								that.startVideoFaceProcess(); // 进行活体检测
							},
							fail: () => {
								that.$refs.loading.closeLoading(); // 关闭loading动画
								that.failTitle = '认证失败'; // 失败的标题
								that.failContent = '出现错误，请及时联系管理员！'; // 失败的提示语
								that.failModal = true; // 失败弹框的显/隐
							}
						});
					},
					fail() {
						that.$refs.loading.closeLoading(); // 关闭loading动画
						that.failTitle = '认证失败'; // 失败的标题
						that.failContent = '出现错误，请及时联系管理员！'; // 失败的提示语
						that.failModal = true; // 失败弹框的显/隐
					}
				});
			},
			// 视频分析
			startVideoFaceProcess() {
				let that = this
				that.$refs.loading.openLoading('人脸视频分析中···'); // 打开loading动画
				let videoData = {
					video: that.faceInfo.videoBase64,
				};
				that.$http
					.post({
						url: '/maintenance/cutVideoV2',
						data: videoData
					})
					.then(res => {
						if (res.code == 200 && res.success) {
							// console.log('后台视频分析返回----', res.data)
							if (res.data.length != 0) {
								that.faceInfo.imageBase64 = res.data[0];
								that.startPicFaceProcess(); // 开始人脸识别
							} else {
								that.$refs.loading.closeLoading(); // 关闭loading动画
								that.failTitle = '认证失败'; // 失败的标题
								that.failContent = '人脸活体视频解析失败, 请重新操作！'; // 失败的提示语
								that.failModal = true; // 失败弹框的显/隐
							}
						} else {
							that.$refs.loading.closeLoading(); // 关闭loading动画
							that.failTitle = '认证失败'; // 失败的标题
							that.failContent = res.msg; // 失败的提示语
							that.failModal = true; // 失败弹框的显/隐
						}
					});
			},
			startPicFaceProcess() {
				let that = this
				that.$refs.loading.openLoading('人脸认证中···'); // 打开loading动画
				uni.request({
					url: 'https://aip.baidubce.com/oauth/2.0/token', //是真实的接口地址
					data: {
						grant_type: 'client_credentials',
						client_id: config.baidu_client_id, // 用你创建的应用的API Key
						client_secret: config.baidu_client_secret // 用你创建的应用的Secret Key
					},
					header: {
						'Content-Type': 'application/json'
					},
					success(res) {
						that.faceInfo.accessToken = res.data.access_token; //获取到token
						//活体检测
						uni.request({
							url: 'https://aip.baidubce.com/rest/2.0/face/v3/faceverify?access_token=' +
								that.faceInfo
								.accessToken,
							method: 'POST',
							data: [{
								image: that.faceInfo.imageBase64,
								image_type: 'BASE64'
							}],
							header: {
								'Content-Type': 'application/json'
							},
							success(res) {
								// console.log(res);
								if (res.data.error_code == 0 && res.data.result.face_liveness >= 0.8) {
									// 人脸库搜索
									uni.request({
										url: 'https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=' +
											that.faceInfo.accessToken,
										method: 'POST',
										data: {
											image: that.faceInfo.imageBase64,
											image_type: 'BASE64',
											group_id_list: config.baidu_group_id,
											liveness_control: 'NORMAL',
											user_id: config.baidu_userid_pre + that.userInfo
												.userIdCard
										},
										header: {
											'Content-Type': 'application/json'
										},
										success(res) {
											// console.log(res);
											if (
												res.data.error_msg == 'SUCCESS' &&
												res.data.result.user_list[0].user_id == config
												.baidu_userid_pre +
												that.userInfo.userIdCard &&
												res.data.result.user_list[0].score > 80
											) {
												that.spotCheckFace(); // 提交抽查
											} else {
												that.$refs.loading.closeLoading(); // 关闭loading动画
												that.failTitle = '认证失败'; // 失败的标题
												that.failContent = res.msg; // 失败的提示语
												that.failModal = true; // 失败弹框的显/隐
												if (res.data.error_code == '222207') {
													that.$refs.loading
														.closeLoading(); // 关闭loading动画
													that.failTitle = '认证失败'; // 失败的标题
													that.failContent =
														'请到个人中心，比对公安人证信息后重试'; // 失败的提示语
													that.failModal = true; // 失败弹框的显/隐
												} else {
													that.$refs.loading
														.closeLoading(); // 关闭loading动画
													that.failTitle = '认证失败'; // 失败的标题
													that.failContent = '请本人进行人脸识别认证！'; // 失败的提示语
													that.failModal = true; // 失败弹框的显/隐
												}
											}
										},
										fail(res) {
											that.$refs.loading.closeLoading(); // 关闭loading动画
											that.failTitle = '认证失败'; // 失败的标题
											that.failContent = '出现错误，请联系管理员！'; // 失败的提示语
											that.failModal = true; // 失败弹框的显/隐
										}
									});
								} else {
									that.$refs.loading.closeLoading(); // 关闭loading动画
									that.failTitle = '认证失败'; // 失败的标题
									that.failContent = '请确保是本人人脸认证！'; // 失败的提示语
									that.failModal = true; // 失败弹框的显/隐
								}
							}
						});
					},
					fail(res) {
						that.$refs.loading.closeLoading(); // 关闭loading动画
						that.failTitle = '认证失败'; // 失败的标题
						that.failContent = '出现错误，请退出后重试！'; // 失败的提示语
						that.failModal = true; // 失败弹框的显/隐
					}
				});
			},
			// 开始审查
			spotCheckFace() {
				let that = this
				let filePath = wx.env.USER_DATA_PATH + '/hym_pay_qrcode.png';
				uni.getFileSystemManager().writeFile({
					filePath: filePath, //创建一个临时文件名
					data: that.faceInfo.imageBase64, //写入的文本或二进制数据
					encoding: 'base64', //写入当前文件的字符编码
					success: res => {
						that.$uploadImg.uploadImgOSSBase64(filePath, 4).then(res => {
							if (res != null && res.length > 0) {
								let checkParams = {
									checkId: that.brushFaceInfo.id,
									checkLongitude: that.faceInfo.longitude,
									checkLatitude: that.faceInfo.latitude,
									faceUrl: res,
									locationResult: 1, // 定位结果(1:成功 2:失败)
									faceResult: 1 // 人脸识别结果(1:成功 2:失败)
								};
								that.$http
									.post({
										url: '/serviceOrg/checkTask/finish',
										data: checkParams
									})
									.then(res => {
										if (res.code == 200 && res.success) {
											that.$refs.loading.closeLoading(); // 关闭loading动画
											that.$refs.uToast.show({
												title: '抽查认证成功！',
												type: 'success'
											});
											that.getSpotTaskList(); // 获取的数据列表
										} else {
											that.$refs.loading.closeLoading(); // 关闭loading动画
											that.failTitle = '认证失败'; // 失败的标题
											that.failContent = '请重新认证！'; // 失败的提示语
											that.failModal = true; // 失败弹框的显/隐
										}
									});
							} else {
								that.$refs.loading.closeLoading(); // 关闭loading动画
								that.failTitle = '认证失败'; // 失败的标题
								that.failContent = '请重新认证！'; // 失败的提示语
								that.failModal = true; // 失败弹框的显/隐
							}
						});
					},
					fail: err => {
						that.$refs.loading.closeLoading(); // 关闭loading动画
						that.failTitle = '认证失败'; // 失败的标题
						that.failContent = '请重新认证！'; // 失败的提示语
						that.failModal = true; // 失败弹框的显/隐
					}
				});
			},
			// 跳转提交材料页面
			submitEvidence(id) {
				this.$pageJump.navigateTo('/pages/maintenance/public/personal/spotTask/components/submitMaterials?id=' +
					id);
			},
			// 跳转材料详情页面
			evidenceDetails(id) {
				this.$pageJump.navigateTo('/pages/maintenance/public/personal/spotTask/components/materialsDetails?id=' +
					id);
			}
		}
	};
</script>

<style lang="scss" scoped>
	.spotTask {
		&-nav {
			position: fixed;
			top: 0;
			left: 0;
			width: 100%;
			z-index: 89;
		}

		&-list {
			margin-top: 116rpx;

			&-box {
				.tips {
					padding: 8rpx 13rpx;
					display: inline;
				}

				.tips1 {
					padding: 6rpx 10rpx;
					border: 2rpx solid #fa4953;
					color: #fa4953;
				}

				.tips2 {
					padding: 6rpx 10rpx;
					border: 2rpx solid #3178ff;
					color: #3178ff;
				}

				.tips3 {
					padding: 6rpx 10rpx;
					border: 2rpx solid #7883a1;
					color: #7883a1;
				}

				.ff-flex-between {
					margin-top: 30rpx;

					image {
						width: 30rpx;
						height: 30rpx;
						margin-right: 5rpx;
					}
				}
			}
		}

		/deep/.u-size-mini {
			font-size: 24rpx !important;
			height: 60rpx !important;
			line-height: 60rpx !important;
		}
	}

	/deep/.u-size-default {
		height: 90rpx !important;
		line-height: 90rpx !important;
	}
</style>